<!DOCTYPE html>
<html lang="en" style="font-size: 20px;">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>函数的深拷贝</title>
  <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div style="background: green; width: 5rem; height: 5rem;display: flex; ">
    <div style="background: lightcoral;width: 1rem; height: 1rem;margin:auto"></div>
  </div>
  <input type="text" readonly>
  <input type="text" disabled>

</body>
<script>

  // 深拷贝实现 --- 包括函数和循环引用
  // weakMap 的使用 ， 函数的深克隆
  function deepClone(value, hash = new WeakMap()) {
    if (value === null) return value;
    if (value === 'function') return new Function("return " + value.toString())()()

    let obj = new value.constructor()
    if (hash.get(value)) {
      return hash.get(value)
    }
    hash.set(value, obj)
    for (let key in value) {
      if (value.hasOwnProperty(key)) {
        obj[key] = deepClone(value[key], hash)
      }
    }
    return obj
  }

  // 左右奇数 和偶数
  function oddEven(str) {
    str = ''+ str;
    if (Number.isNaN(Number(str))) return;
    var arr = str.split('').map(v => Number(v));
    var result = [];
    arr.forEach(function (v) {
      if (v % 2) {
        result.unshift(v)
      } else {
        result.push(v)
      }
    })
    return result;
  }

  
  // 第一个不重复的数字，没有返回false
  function firstUniq(str) {
    str = ''+ str;
    var arr = str.split('');
    
    var hash = {};
    var result = false;

    for(var i = 0;i < arr.length; i++){
      if(hash[arr[i]]){
        hash[arr[i]] ++
      }else{
        hash[arr[i]] = 1
      }
    }
    for(var j = 0;j< arr.length; j++){
      if(hash[arr[j]] == 1){
        result = arr[j]
        break
      }
    }
    return result
  }

  
 // 函数的深拷贝  , 字符串的执行 es5 中只有  eval 和new Function 
 var test = function () { console .log('1')}
 function cloneAfun(f){
    var funBody = f.toString().split('{')[1].split('}')[0]
    return new Function(`${funBody}`)
 }


// 循环引用问题 weakmap 发挥的时候了,注意直接初始化 循环引用是报错的护着undefined
var t = { d :'k'}
var obj  = {}
t.key = obj;
obj.t = t;

// map 的key 可以是任何的数据， weakmap 存储引用不会内存泄漏，每次递归前进行该引用存在判断，存在就直接返回
function deepClone (obj, wm = new WeakMap()) {
  if (obj === null || typeof obj !== "object") return obj;
  let result = {};
  
  if(wm.get(obj)){
    return wm.get(obj);
  } 
  wm.set(obj,obj)

  for (var key in  obj) {
    result[key] = deepClone (obj[key], wm)
  }
  return result;
}

var t = {a : 1 }
var o = {a : 2 }
var k = {...o, ...t}

console.log(0.1.toFixed())


</script>

</html>